///*****************************************Copyright(C)******************************************
//****************************************** *********************************************
//*------------------------------------------文件信息---------------------------------------------
//* FileName          : NB_IOT.c
//* Author            : 张婷颖
//* Version           : 1.0V
//* Description       :
//*----------------------------------------历史版本信息-------------------------------------------
//* History           :
//* Description       :
//*-----------------------------------------------------------------------------------------------
//***********************************************************************************************/
///* Includes-----------------------------------------------------------------------------------*/
//#include "NB_IOT.h"
//#include "bsp_uart.h"
//#include "stdio.h"
//#include "stdlib.h"
//#include "stdbool.h"
//
//#if NB_IOT
///* Private define-----------------------------------------------------------------------------*/
//
///* Private typedef----------------------------------------------------------------------------*/
//
///* Private macro------------------------------------------------------------------------------*/
//
///* Private variables--------------------------------------------------------------------------*/
//NBIOT_FLAG_t nbiot_status = NBIOT_INIT;                                    //初始状态为透传
//int i;
//#if MQTT_NB_IOT
//_nbiot_atcmd_st nb_mqtt_param_info[] = {
//		/*1.选择工作模式为：通道1 MQTT透传模式*/
//		{5, "AT+DTUMODE\r\n",        "AT+DTUMODE=2,1\r\n"},
//
//		/*2.配置MQTT透传模式的工作参数*/
//		{5, "AT+IPPORT\r\n",         "AT+IPPORT=\"cloud.alientek.com\",1833,1\r\n"},
//		{5, "AT+CLIENTID\r\n",       "AT+CLIENTID=\"clientid\",1\r\n"},
//		{5, "AT+USERPWD\r\n",        "AT+USERPWD=\"user\",\"password\",1\r\n"},
//		{5, "AT+WILL\r\n",           "AT+WILL=\" \",\" \",0,0,1\r\n"},
//		{5, "AT+CLEANSESSION\r\n",   "AT+CLEANSESSION=0,1\r\n"},
//		{5, "AT+MQTTKEEP\r\n",       "AT+MQTTKEEP=120,1\r\n"},
//		{5, "AT+BLOCKINFO\r\n",      "AT+BLOCKINFO=0,1\r\n"},
//		{5, "AT+MQTTSUB\r\n",        "AT+MQTTSUB=1,\"sub\",0,1,1\r\n"},
//		{5, "AT+MQTTPUB\r\n",        "AT+MQTTPUB=1,\"pub\",0,0,1,1\r\n"},
//
//		/*3.其他参数功能配置*/
//		{5, "AT+TCPMODBUS\r\n",      "AT+TCPMODBUS=0,1\r\n"},
//		{5, "AT+TCPHEX\r\n",         "AT+TCPHEX=0,1\r\n"},
//		{5, "AT+KEEPALIVE\r\n",      "AT+KEEPALIVE=0,0,\" \",1\r\n"},
////		{5, "AT+DTUID\r\n",          "AT+DTUID=0,0,0,\" \",1\r\n"},
//	   };
//#endif
//
//#if MODBUS_NB_IOT
//_nbiot_atcmd_st nb_net_param_info[]= {
//
//		/*1.选择工作模式为：通道2 网络透传模式*/
//		{5, "AT+DTUMODE\r\n",        "AT+DTUMODE=1,2\r\n"},
//
//		/*2.配置网络透传模式的工作参数*/
//		{5, "AT+DSCADDR\r\n",   "AT+DSCADDR=2,\"TCP\",\"ip\",5020\r\n"},
//		{5, "AT+SECSERVER\r\n",     "AT+SECSERVER=0,2\r\n"},
//
//		/*6.其他参数功能配置*/
//		{5, "AT+TCPMODBUS\r\n",      "AT+TCPMODBUS=0,2\r\n"},
//		{5, "AT+TCPHEX\r\n",         "AT+TCPHEX=0,2\r\n"},
//		{5, "AT+KEEPALIVE\r\n",      "AT+KEEPALIVE=0,0,\" \",2\r\n"},
////		{5, "AT+DTUID\r\n",          "AT+DTUID=0,0,\" \",2\r\n"},
//		};
//#endif
//
//#if MODBUS_NB_IOT
//
//#if COIL_TCP_NB                                                                     //定义modbus读取的线圈及寄存器地址和数量
//uint16_t coil_mnb_addr[SUM_COIL_CON_TCP_NB]=COIL_TCP_NB_ADDR;
//uint8_t coil_mnb_num[SUM_COIL_CON_TCP_NB]=COIL_TCP_NB_NUM;
//#endif  /*COIL_TCP_NB*/
//#if REGISTER_TCP_NB
//uint16_t reg_mnb_addr[SUM_REG_CON_TCP_NB]=REG_TCP_NB_ADDR;
//uint8_t reg_mnb_num[SUM_REG_CON_TCP_NB]=REG_TCP_NB_NUM;
//#endif  /*REGISTER_TCP_NB*/
//
//INFO_COMBINATION mnb_sum_info;
//bool rx_finsh_mnb = 0;
//int i_readcont_mnb = 0,j_readcont_mnb = 0;
//#endif  /*MODBUS_NB_IOT*/
///* Private function prototypes----------------------------------------------------------------*/
//
///* Private functions--------------------------------------------------------------------------*/
//
///************************************************
//函数名称 ： send_data_to_nb
//功    能 ：发送数据给nb
//参    数 ：发送的数据及长度
//返 回 值 ：
//*************************************************/
//void send_data_to_nb(uint8_t *data, uint32_t size)
//{
//	Send_Data(&huart4,data,size);
//}
///************************************************
//函数名称 ： send_cmd_to_nb
//功    能 ：发送指令给nb
//参    数 ：发送的数据及长度
//返 回 值 ：2重启成功 1应答与发送指令相同  0配置成功  -1配置失败  -2超时
//*************************************************/
//static int send_cmd_to_nb(char *cmd, char *ask, uint32_t timeout)
//{
//	send_data_to_nb((uint8_t *)cmd, strlen(cmd));                              //发送指令给NB
//	while(!nbiot_rx_flag)                                                      //等待应答，超时退出
//	{
//		timeout--;
//		if (timeout == 0)
//		{
//			return -2;
//		}
//		HAL_Delay(100);
//	}
//	if(nbiot_rx_flag)                                                           //接收应答，检查应答信息
//	{
//		nbiot_rx_flag = 0;
//		if (strstr((char *)nbiot_rx_buffer, ask) != NULL)
//		{
//			return 1;
//		}
//		else if (strstr((char *)nbiot_rx_buffer, "OK") != NULL)
//		{
//			return 0;
//		}
//		else if (strstr((char *)nbiot_rx_buffer, "Ready") != NULL)
//		{
//			return 2;
//		}
//		else if (strstr((char *)nbiot_rx_buffer, "ERROR") != NULL)
//		{
//			return -1;
//		}
//
//	}
//	return 0;
//}
///************************************************
//函数名称 ： nb_save_configmode
//功    能 ：nb保存配置
//参    数 ：无
//返 回 值 ：0 保存成功  -1 保存失败
//*************************************************/
//static int nb_save_configmode(void)
//{
//    int res;
//    /* 发送+++准备进入配置状态 */
//    res = send_cmd_to_nb("AT&W\r\n", "OK", 5);
//    if (res == -2)                                               /*返回ERRRO表示NB未进入配置状态*/
//    {
//        return -1;
//    }
//
//#if MQTT_NB_IOT
//    free(nb_mqtt_param_info[1].write_cmd);                      // 释放内存
//    nb_mqtt_param_info[1].write_cmd = NULL;                     // 防止悬挂指针
//    free(nb_mqtt_param_info[2].write_cmd);                      // 释放内存
//	nb_mqtt_param_info[2].write_cmd = NULL;                     // 防止悬挂指针
//	free(nb_mqtt_param_info[3].write_cmd);                      // 释放内存
//	nb_mqtt_param_info[3].write_cmd = NULL;                     // 防止悬挂指针
//	free(nb_mqtt_param_info[5].write_cmd);                      // 释放内存
//	nb_mqtt_param_info[5].write_cmd = NULL;                     // 防止悬挂指针
//	free(nb_mqtt_param_info[8].write_cmd);                      // 释放内存
//	nb_mqtt_param_info[8].write_cmd = NULL;                     // 防止悬挂指针
//	free(nb_mqtt_param_info[9].write_cmd);                      // 释放内存
//	nb_mqtt_param_info[9].write_cmd = NULL;                     // 防止悬挂指针
//#endif
//#if MODBUS_NB_IOT
//	free(nb_net_param_info[1].write_cmd);                      // 释放内存
//	nb_net_param_info[1].write_cmd = NULL;                     // 防止悬挂指针
//#endif
//
//    return 0;
//}
///************************************************
//函数名称 ： nb_enter_configmode
//功    能 ：nb进入配置模式
//参    数 ：无
//返 回 值 ：0 进入配置模式成功  -1进入配置模式失败
//*************************************************/
//static int nb_enter_configmode(void)
//{
//    int res;
//
//    /* 发送+++准备进入配置状态 */
//    res = send_cmd_to_nb("+++", "OK", 5);
//    if (res == -2)                                               /*返回ERRRO表示NB未进入配置状态*/
//    {
//        return -1;
//    }
//
//    return 0;
//}
///************************************************
//函数名称 ： nb_reset
//功    能 ：nb重启
//参    数 ：无
//返 回 值 ：0 重启成功  -1进入透传模式失败
//*************************************************/
//static int nb_reset(void)
//{
//    if (send_cmd_to_nb("AT+CFUN=1,1\r\n", "OK", 5) >= 0)
//    {
//        return 0;
//    }
//
//    return -1;
//}
///************************************************
//函数名称 ： nb_enter_transfermode
//功    能 ：nb进透传模式
//参    数 ：无
//返 回 值 ：0 进入透传模式成功  -1进入透传模式失败
//*************************************************/
//static int nb_enter_transfermode(void)
//{
//    if (send_cmd_to_nb("ATO\r\n", "OK", 5) >= 0)
//    {
//        return 0;
//    }
//
//    return -1;
//}
///************************************************
//函数名称 ： nb_cmd_parameter
//功    能 ：nb命令参设设置
//参    数 ：无
//返 回 值 ：0 进入透传模式成功  -1进入透传模式失败
//*************************************************/
//static void nb_cmd_parameter(void)
//{
//	char command[100];
//#if MODBUS_NB_IOT
//	snprintf(command, sizeof(command), "AT+DSCADDR=%s,\"TCP\",\"%s\",%s\r\n", "2",NB_IP, NB_PORT);      // IP PORT
//	nb_net_param_info[1].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_net_param_info[1].write_cmd != NULL)
//		strcpy(nb_net_param_info[1].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for ip port \n");
//#endif /*MODBUS_NB_IOT*/
//
//#if MQTT_NB_IOT
//
//	snprintf(command, sizeof(command), "AT+IPPORT=\"%s\",%s,1\r\n", NB_Broker_Address, NB_Broker_Port);   // MQTT服务器地址
//	nb_mqtt_param_info[1].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[1].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[1].write_cmd, command);                                                // 复制字符串到结构体指针
//    else
//		printf("Memory allocation failed for ip \n");
//
//	snprintf(command, sizeof(command), "AT+CLIENTID=\"%s\",1\r\n", NB_Client_ID);                         //clientid
//	nb_mqtt_param_info[2].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[2].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[2].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for client id\n");
//
//	snprintf(command, sizeof(command), "AT+USERPWD=\"%s\",\"%s\",1\r\n", NB_User_Name,NB_Password);            //user password
//	nb_mqtt_param_info[3].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[3].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[3].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for user password\n");
//
//	snprintf(command, sizeof(command), "AT+CLEANSESSION=%s,1\r\n", NB_Clean_status);            // clean
//	nb_mqtt_param_info[5].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[5].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[5].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for clean\n");
//
//	snprintf(command, sizeof(command), "AT+MQTTSUB=1,\"%s\",%s,1,1\r\n", NB_Sub_Topic,NB_QOS);           // sub
//	nb_mqtt_param_info[8].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[8].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[8].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for sub\n");
//
//	snprintf(command, sizeof(command), "AT+MQTTPUB=1,\"%s\",%s,0,1,1\r\n", NB_Pub_Topic,NB_QOS);         //pub
//	nb_mqtt_param_info[9].write_cmd = (char *)malloc(strlen(command) + 1);                               // 分配内存
//	if (nb_mqtt_param_info[9].write_cmd != NULL)
//		strcpy(nb_mqtt_param_info[9].write_cmd, command);                                                // 复制字符串到结构体指针
//	else
//		printf("Memory allocation failed for pub\n");
//
//#endif /*MQTT_NB_IOT*/
//}
//
///************************************************
//函数名称 ： nb_config_work_param
//功    能 ：配置nb工作参数
//参    数 ：指令参数，需要配置的指令个数
//返 回 值 ： 0所有指令配置成功，n第几个指令配置不成功
//*************************************************/
//static int nb_config_work_param(_nbiot_atcmd_st *work_param, uint8_t num)
//{
////    int i;
//    int res = 0;
//
//    for (i = 0; i < num; i++)
//    {
//        res = send_cmd_to_nb((work_param + i)->read_cmd,
//                              (work_param + i)->write_cmd + strlen((work_param + i)->read_cmd) - 1,
//                              work_param[i].timeout);
//
//        if (res == 1)                                            //如果NB内部参数和需要配置的参数一致，不需要重复去配置
//        {
//            continue;
//        }
//        else                                                     //NB内部参数与配置参数不一致，需要更新DTU内部参数
//        {
//            res = send_cmd_to_nb((work_param + i)->write_cmd,"OK",(work_param + i)->timeout);
//
//            if (res < 0)
//            {
//                return i+1;
//            }
//        }
//    }
//
//    return 0;
//}
///************************************************
//函数名称 ： nbiot_config_init
//功    能 ：nb配置初始化
//参    数 ：配置的模式
//返 回 值 ： 0 初始化成功，-1进入配置模式失败，-2参数配置失败，-3保存参数，-4进入透传模式失败
//*************************************************/
//int nbiot_config_init(_nbiot_work_mode_eu work_mode)
//{
//	int res;
//	nb_cmd_parameter();                                                             //生成AT指令
//	/*1.进入配置状态*/
//	res = nb_enter_configmode();
//	if ( res != 0 )return -1;
//
//	/*2.配置工作参数*/
//	switch (work_mode)
//	{
//#if MODBUS_NB_IOT
//		case NB_WORKMODE_NET:
//		{
//			res = nb_config_work_param((_nbiot_atcmd_st *)&nb_net_param_info, sizeof(nb_net_param_info) / sizeof(_nbiot_atcmd_st));
//			break;
//		}
//#endif /*MODBUS_NB_IOT*/
//
//#if MQTT_NB_IOT
//		case NB_WORKMODE_MQTT:
//		{
//			res = nb_config_work_param((_nbiot_atcmd_st *)&nb_mqtt_param_info, sizeof(nb_mqtt_param_info) / sizeof(_nbiot_atcmd_st));
//			break;
//		}
//#endif /*MQTT_NB_IOT*/
//		default:break;
//	}
//	if( res != 0 )return -2;
//
//	/*3.保存参数*/
//	res = nb_save_configmode();
//	if( res != 0 )return -3;
//
//	/*4.重启进入透传状态*/
//	res = nb_reset();
//	if( res != 0 )return -4;
//	nbiot_status = NBIOT_DATA;
//	return 0;
////	res = nb_enter_transfermode();
////	if( res != 0 )return -4;
////
////	return 0;
//}
//
//#if MODBUS_NB_IOT
///************************************************
//函数名称 ： M_Analyse_info_MNB
//功    能 ： 分析接收到的信息帧
//参    数 ： p 接收缓存首地址   len  接收数据长度
//返 回 值 ： 无
//*************************************************/
//void M_Analyse_info_MNB(uint8_t *p,uint8_t Len)
//{
//	rx_finsh_mnb = M_Analyse_info_TCP(p,Len,&mnb_sum_info);                        //进入MODBUS解析过程,其他内容这里面都完成了
//}
///************************************************
//函数名称 ： RX_Parse_Data_MNB
//功    能 ： 主循环分别解析处理接收的数据
//参    数 ： mnb_sum_info 协议解析后的数据
//返 回 值 ： 无
//*************************************************/
//void RX_Parse_Data_MNB(INFO_COMBINATION *mnb_sum_info)
//{
//	if(rx_finsh_mnb)                                                                  //接收了新数据
//	{
//		rx_finsh_mnb = 0;
//		switch(mnb_sum_info->recvinfo.funcode)
//		{
//			case FUNCODE_01:
//			case FUNCODE_02:
//				if(M_check_code01_02(&(mnb_sum_info->rx_data), &(mnb_sum_info->tx_data),  mnb_sum_info->rebuf))                  //返回错误，重发请求
//				   rerequest(mnb_sum_info);
//				else
//				{
//					mnb_sum_info->master_status = FINISH;                                                                //本次请求完成
//				   refresh_info(mnb_sum_info);                                                                          //清除本次请求 响应
//				   mnb_sum_info->send_count = 0;                                                                        //从站信息正常，清除重发次数
//				}
//				break;
//			case FUNCODE_03:
//			case FUNCODE_04:
//				if(M_check_code03_04(&(mnb_sum_info->rx_data), &(mnb_sum_info->tx_data),  mnb_sum_info->rebuf))                  //返回错误，重发请求
//				   rerequest(mnb_sum_info);
//				else
//				{
//					mnb_sum_info->master_status = FINISH;                                                                //本次请求完成
//				   refresh_info(mnb_sum_info);                                                                          //清除本次请求 响应
//				   mnb_sum_info->send_count = 0;                                                                        //从站信息正常，清除重发次数
//				}
//				break;
//			case FUNCODE_05:
//			case FUNCODE_06:
//				if(M_check_code05_06(&(mnb_sum_info->rx_data), &(mnb_sum_info->tx_data), mnb_sum_info->rebuf))                                      //返回错误，重发请求
//				   rerequest(mnb_sum_info);
//				else
//				{
//					mnb_sum_info->master_status = FINISH;                                               //本次请求完成
//				   refresh_info(mnb_sum_info);                                                       //清除本次请求 响应
//				   mnb_sum_info->send_count = 0;                                                       //从站信息正常，清除重发次数
//				}
//				break;
//			case FUNCODE_0F:
//			case FUNCODE_10:
//				if(M_check_code0f_10(&(mnb_sum_info->rx_data), &(mnb_sum_info->tx_data),  mnb_sum_info->rebuf))                                     //返回错误，重发请求
//				   rerequest(mnb_sum_info);
//				else
//				{
//					mnb_sum_info->master_status = FINISH;                                               //本次请求完成
//				   refresh_info(mnb_sum_info);                                                       //清除本次请求 响应
//				   mnb_sum_info->send_count = 0;                                                       //从站信息正常，清除重发次数
//				}
//				break;
//			default:   break;
//		}
//	}
//}
///************************************************
//函数名称 ： M485_read
//功    能 ： MODBUS根据读取要求，读取线圈寄存器数据
//参    数 ：
//返 回 值 ： 无
//*************************************************/
//void MNB_read(void)
//{
//	if(mnb_sum_info.read_finish == 0)
//	{
//#if COIL_TCP_NB
//		if(!j_readcont_mnb)
//		{
//			M_achieves_read_TCP(MODBUS_TCP_NB_ADDR,FUNCODE_01,coil_mnb_addr[0],coil_mnb_num[0],&mnb_sum_info);
//			j_readcont_mnb++;
//		}
//
//		if ((mnb_sum_info.master_status == FINISH)|
//			(mnb_sum_info.master_status == ABANDON_REQUEST))                                                //当上一次请求完成或放弃，更改请求，发送下一次请求
//		{
//			if(j_readcont_mnb < SUM_COIL_CON_TCP_NB)
//			{
//				M_achieves_read_TCP(MODBUS_TCP_NB_ADDR,FUNCODE_01,coil_mnb_addr[j_readcont_mnb],coil_mnb_num[j_readcont_mnb],&mnb_sum_info);
//				j_readcont_mnb++;
//			}
//#if REGISTER_TCP_NB & COIL_TCP_NB
//			else if((REGISTER_TCP_NB)&(j_readcont_mnb >= SUM_COIL_CON_TCP_NB)){
//				if(j_readcont_mnb < SUM_REG_CON_TCP_NB)
//				{
//					M_achieves_read_TCP(MODBUS_TCP_NB_ADDR,FUNCODE_03,reg_mnb_addr[j_readcont_mnb],reg_mnb_num[j_readcont_mnb],&mnb_sum_info);
//					j_readcont_mnb++;
//				}
//				else {
//					mnb_sum_info.read_finish = 1;
//					j_readcont_mnb = 0;
//					j_readcont_mnb = 0;
//					mnb_sum_info.read_finish = 0;                      //用于循环测试
//				}
//			}
//#elif                                                              //只有线圈
//			else {
//				mnb_sum_info.read_finish = 1;
//				j_readcont_mnb = 0;
//				j_readcont_mnb = 0;
//				mnb_sum_info.read_finish = 0;                      //用于循环测试
//			}
//#endif	/*REGISTER_TCP_NB & COIL_TCP_NB*/
//		}
//#endif  /*COIL*/
//#if REGISTER_TCP_NB & (!COIL_TCP_NB)                                             //无线圈时先从寄存器开始读取
//		if(!j_readcont_mnb)
//		{
//			M_achieves_read_TCP(MODBUS_TCP_NB_ADDR,FUNCODE_03,reg_mnb_addr[0],reg_mnb_num[0],&mnb_sum_info);
//			j_readcont_mnb++;
//		}
//		if ((mnb_sum_info.master_status == FINISH)|
//			(mnb_sum_info.master_status == ABANDON_REQUEST))                                                //当上一次请求完成或放弃，更改请求，发送下一次请求
//		{
//			if(j_readcont_mnb < SUM_REG_CON_TCP_NB)
//			{
//				M_achieves_read_TCP(MODBUS_TCP_NB_ADDR,FUNCODE_03,reg_mnb_addr[j_readcont_mnb],reg_mnb_num[j_readcont_mnb],&mnb_sum_info);
//				j_readcont_mnb++;
//			}
//			else {
//				mnb_sum_info.read_finish = 1;
//				j_readcont_mnb = 0;
//				j_readcont_mnb = 0;
//			}
//
//		}
//#endif  /*ONLY COIL_TCP_NB*/
//	}
//}
//#endif  /*MODBUS_NB_IOT*/
//
//#endif /*NB_IOT*/
//
//
